/*****************************************************************
Wowengine - v0.1

File: wen_spatial.h
Creation date: 2012-10-15
*****************************************************************/

/****************************************************************/
#ifndef WEN_SPATIAL_H
#define WEN_SPATIAL_H
//----------------------------------------------------------------
#include "wen_transformation.h"
#include "system/wen_system.h"
#include "graphics/wen_render.h"
#include "bvh/wen_bvh.h"
//----------------------------------------------------------------
#define TYPE_NODE	0
#define TYPE_MESH	1
//----------------------------------------------------------------

namespace wen
{
//----------------------------------------------------------------

class WEN_API Spatial
{
	DECLARE_SMART_POINTER(Spatial);

public:	
	virtual ~Spatial();

	Spatial* GetParent() const;
	void SetParent(Spatial* parent);

	const D3DXMATRIX* GetWorldTransformation() const;
	const D3DXMATRIX* GetLocalTransformation() const;

	void SetWorldTransformation(Transformation& worldTrans);
	void SetLocalTransformation(Transformation& localTrans);

	virtual void Draw(Render& rkRender);

	void Update(float fTimeBetweenFrames);

	//Position
	void SetPos(float fPosX, float fPosY, float fPosZ);
	inline float GetPosX() const { return m_kPosition.x; }
	inline float GetPosY() const { return m_kPosition.y; }
	inline float GetPosZ() const { return m_kPosition.z; }

	//Rotation
	void SetRotationByQuaternion(float fRotationX, float fRotationY, float fRotationZ, float fRotationW);
	inline const D3DXQUATERNION* GetQuaternionRotation() const { return &m_kRotation; }

	void SetRotation(float fRotationX, float fRotationY, float fRotationZ);
	inline float GetRotationX() const { return m_kRotationAxis.x; }
	inline float GetRotationY() const { return m_kRotationAxis.y; }
	inline float GetRotationZ() const { return m_kRotationAxis.z; }

	//Scale
	void SetDim(float fWidth, float fHeight, float fDepth);
	inline float GetWidth() const { return m_kScale.x; }
	inline float GetHeight() const { return m_kScale.y; }
	inline float GetDepth() const { return m_kScale.z; }

	inline void SetVisible(bool value) { m_bVisible = value; }
	inline bool IsVisible() const { return m_bVisible; }

	void UpdateWorldTransformInfo();

	void CalculateMatrix();

	//Bvh
	bool CheckBVHFrustumCollision(BVH* theBvh, Render& theRender);

	virtual BVH* GetBVH() { return NULL; }

	virtual void UpdateBoundingVolume(Render& rkRender){;}

	void SetTransformedBVH(BVH* transformed) {m_pkTransformedBV = transformed;}
	BVH* GetTransformedBVH() {return m_pkTransformedBV;}

	void CalculateBVH(Render& rkRender);

	//Type Node/Mesh
	int type;

	//Name Stuff
	const std::string& GetName() { return m_strName; }
	void SetName(const std::string& name) {m_strName = name;}

protected:
	Spatial(); //To be an abstract class

	Spatial* m_pkParent;	

	bool m_bVisible;

	std::string m_strName;

	D3DXVECTOR3 m_kPosition;
	D3DXVECTOR3 m_kScale;
	D3DXVECTOR3 m_kRotationAxis;
	D3DXQUATERNION m_kRotation;

	D3DXMATRIX m_localTransform;
	D3DXMATRIX m_worldTransform;

	BVH* m_pkModelBV;
	BVH* m_pkTransformedBV;
};
//----------------------------------------------------------------
} // end namespace
//----------------------------------------------------------------
#endif // WEN_SPATIAL_H
//----------------------------------------------------------------